package com.easy.sk.system.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easy.common.bean.SeckillActivity;
import com.easy.common.bean.SeckillGoods;
import com.easy.common.exception.ServiceException;
import com.easy.common.service.ISeckillActivityService;
import com.easy.common.util.SYS;
import com.easy.sk.system.mapper.SeckillActivityMapper;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@DubboService
public class SeckillActivityServiceImpl extends ServiceImpl<SeckillActivityMapper, SeckillActivity> implements ISeckillActivityService {
    @Autowired
    SeckillGoodsServiceImpl seckillGoodsService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public boolean startPreheat(Integer id) {
        //参数id 秒杀活动id
        //redis中是否有这个活动,如果有,则已经开启
        String activity_redis_key =SYS.SK_PRE_ACTIVITY_KEY + id;
        if(redisTemplate.hasKey(activity_redis_key)){
            throw new ServiceException("活动已经预热");
        }
        //获取数据库中的活动信息
        SeckillActivity activity=this.getById(id);
        if(activity == null){
            throw new ServiceException("活动不存在");
        }
        if(activity.getStatus() != 0){
            throw new ServiceException("活动状态异常");
        }
        LocalDateTime endTime = activity.getEnd_time();
        //活动结束时间毫秒数
        Long endTimeMillis = endTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        LocalDateTime startTime = activity.getStart_time();
        //活动开始时间毫秒数
        Long startTimeMillis = startTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        //当前时间毫秒数
        Long currentTimeMillis = System.currentTimeMillis();
        //缓存有效时间 时间片段
        Long expireTime = endTimeMillis - currentTimeMillis;
        if(currentTimeMillis > endTimeMillis){
            throw new ServiceException("活动已结束");
        }
        //开始预热操作
        //1.将活动信息保存到redis中
        Map<String, Object> activityMap=new HashMap<>();
        activityMap.put(SYS.SK_ACTIVITY_STATUS_HASH_KEY, 1);
        activityMap.put(SYS.SK_ACTIVITY_START_TIME_KEY, startTimeMillis);
        activityMap.put(SYS.SK_ACTIVITY_END_TIME_KEY, endTimeMillis);
        redisTemplate.opsForHash().putAll(activity_redis_key, activityMap);
        redisTemplate.expire(activity_redis_key, expireTime, java.util.concurrent.TimeUnit.MILLISECONDS);

        //2.将秒杀商品信息保存到redis中
        //获取数据库中的秒杀商品信息
        QueryWrapper<SeckillGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SeckillGoods::getActivity_id, id).eq(SeckillGoods::getIs_del, 0);//sql where id=?
        List<SeckillGoods> seckillGoods = seckillGoodsService.list(queryWrapper);
        for (SeckillGoods seckillGoods1 : seckillGoods) {
            String goods_redis_key = SYS.SK_PRE_GOODS_KEY + seckillGoods1.getId();//存入redis的秒杀商品的key
            int sk_stock = seckillGoods1.getStock();//秒杀库存
            redisTemplate.opsForValue().set(goods_redis_key, sk_stock, expireTime, java.util.concurrent.TimeUnit.MILLISECONDS);
        }
        //修改数据库中秒杀活动的状态
        activity.setStatus(1);
        activity.setUpdate_time(LocalDateTime.now());
        this.updateById(activity);
        return true;
    }

    @Override
    public boolean start(Integer id) {
        return false;
    }
    @Override
    public boolean clear(Integer id) {
        return false;
    }

    @Override
    public SeckillActivity getActivityById(int id) {
        return super.getOne(new QueryWrapper<SeckillActivity>().eq("id", id));
    }

    @Override
    public SeckillActivity getActivityByName(String name) {
        return super.getOne(new QueryWrapper<SeckillActivity>().eq("name", name));
    }

    @Override
    public int addActivity(SeckillActivity activity) {
        // 确保删除状态默认为0(未删除)
        if (activity.getIs_del() == null) {
            activity.setIs_del(0);
        }
        // 确保状态默认为0(未开始)
        if (activity.getStatus() == null) {
            activity.setStatus(0);
        }
        return super.save(activity) ? 1 : 0;
    }

    @Override
    public int updateActivity(SeckillActivity activity) {
        activity.setUpdate_time(LocalDateTime.now());
        return super.updateById(activity) ? 1 : 0;
    }

    @Override
    public int deleteActivity(Integer id) {
        // 软删除，将is_del字段置为1
        return super.update().set("is_del", 1).eq("id", id).update() ? 1 : 0;
    }

    @Override
    public int updateStatus(Integer id, Integer status) {
        return super.update().set("status", status).eq("id", id).update() ? 1 : 0;
    }

    @Override
    public List<SeckillActivity> getAll(SeckillActivity activity) {
        LambdaQueryWrapper<SeckillActivity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SeckillActivity::getIs_del, 0);
        return super.list(queryWrapper);
    }

    @Override
    public IPage<SeckillActivity> getPage(SeckillActivity activity, IPage<SeckillActivity> page) {
        LambdaQueryWrapper<SeckillActivity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SeckillActivity::getIs_del, 0);
        return super.page(page, queryWrapper);
    }
}
